package sort

import (
	"errors"
	"fmt"
	"sort"
	"time"
)

// Sort 排序,目前支持自带类型
// 默认正序排序
// 类型判定,速度慢8倍
func Sort(list interface{}, desc ...bool) error {
	switch l := list.(type) {
	case []int:
		SortInt(l, desc...)
	case *[]int:
		SortInt(*l, desc...)
	case []int8:
		SortInt8(l, desc...)
	case *[]int8:
		SortInt8(*l, desc...)
	case []int16:
		SortInt16(l, desc...)
	case *[]int16:
		SortInt16(*l, desc...)
	case []int32:
		SortInt32(l, desc...)
	case *[]int32:
		SortInt32(*l, desc...)
	case []int64:
		SortInt64(l, desc...)
	case *[]int64:
		SortInt64(*l, desc...)
	case []uint8:
		SortUint8(l, desc...)
	case *[]uint8:
		SortUint8(*l, desc...)
	case []uint16:
		SortUint16(l, desc...)
	case *[]uint16:
		SortUint16(*l, desc...)
	case []uint32:
		SortUint32(l, desc...)
	case *[]uint32:
		SortUint32(*l, desc...)
	case []uint64:
		SortUint64(l, desc...)
	case *[]uint64:
		SortUint64(*l, desc...)
	case []string:
		SortString(l, desc...)
	case *[]string:
		SortString(*l, desc...)
	case []float32:
		SortFloat32(l, desc...)
	case *[]float32:
		SortFloat32(*l, desc...)
	case []float64:
		SortFloat64(l, desc...)
	case *[]float64:
		SortFloat64(*l, desc...)
	case []time.Time:
		SortTime(l, desc...)
	case *[]time.Time:
		SortTime(*l, desc...)
	default:
		return errors.New(fmt.Sprintf("不支持类型:%T", list))
	}
	return nil
}

// SortInt64 排序int64类型
func SortInt64(list []int64, desc ...bool) {
	sort.Sort(newSortInt64(list, len(desc) > 0 && desc[0]))
}

// SortInt 排序int类型
func SortInt(list []int, desc ...bool) {
	list2 := []int64{}
	for _, v := range list {
		list2 = append(list2, int64(v))
	}
	sort.Sort(newSortInt64(list2, len(desc) > 0 && desc[0]))
	list = list[0:0]
	for _, v := range list2 {
		list = append(list, int(v))
	}
}

//
func SortInt32(list []int32, desc ...bool) {
	list2 := []int64{}
	for _, v := range list {
		list2 = append(list2, int64(v))
	}
	sort.Sort(newSortInt64(list2, len(desc) > 0 && desc[0]))
	list = list[0:0]
	for _, v := range list2 {
		list = append(list, int32(v))
	}
}

//
func SortInt16(list []int16, desc ...bool) {
	list2 := []int64{}
	for _, v := range list {
		list2 = append(list2, int64(v))
	}
	sort.Sort(newSortInt64(list2, len(desc) > 0 && desc[0]))
	list = list[0:0]
	for _, v := range list2 {
		list = append(list, int16(v))
	}
}

//
func SortInt8(list []int8, desc ...bool) {
	list2 := []int64{}
	for _, v := range list {
		list2 = append(list2, int64(v))
	}
	sort.Sort(newSortInt64(list2, len(desc) > 0 && desc[0]))
	list = list[0:0]
	for _, v := range list2 {
		list = append(list, int8(v))
	}
}

//
func SortUint64(list []uint64, desc ...bool) {
	sort.Sort(newSortUint64(list, len(desc) > 0 && desc[0]))
}

//
func SortUint32(list []uint32, desc ...bool) {
	list2 := []uint64{}
	for _, v := range list {
		list2 = append(list2, uint64(v))
	}
	sort.Sort(newSortUint64(list2, len(desc) > 0 && desc[0]))
	list = list[0:0]
	for _, v := range list2 {
		list = append(list, uint32(v))
	}
}

//
func SortUint16(list []uint16, desc ...bool) {
	list2 := []uint64{}
	for _, v := range list {
		list2 = append(list2, uint64(v))
	}
	sort.Sort(newSortUint64(list2, len(desc) > 0 && desc[0]))
	list = list[0:0]
	for _, v := range list2 {
		list = append(list, uint16(v))
	}
}

//
func SortUint8(list []uint8, desc ...bool) {
	list2 := []uint64{}
	for _, v := range list {
		list2 = append(list2, uint64(v))
	}
	sort.Sort(newSortUint64(list2, len(desc) > 0 && desc[0]))
	list = list[0:0]
	for _, v := range list2 {
		list = append(list, uint8(v))
	}
}

// SortString 排序字符串类型,string
//[0 1 10 100 11 2 20]
func SortString(list []string, desc ...bool) {
	sort.Sort(newSortString(list, len(desc) > 0 && desc[0]))
}

// SortFloat32 排序浮点类型,float32,
func SortFloat32(list []float32, desc ...bool) {
	list2 := []float64{}
	for _, v := range list {
		list2 = append(list2, float64(v))
	}
	sort.Sort(newSortFloat64(list2, len(desc) > 0 && desc[0]))
	list = list[0:0]
	for _, v := range list2 {
		list = append(list, float32(v))
	}
}

// SortFloat64 排序浮点类型,float64
func SortFloat64(list []float64, desc ...bool) {
	sort.Sort(newSortFloat64(list, len(desc) > 0 && desc[0]))
}

func SortTime(list []time.Time, desc ...bool) {
	sort.Sort(newSortTime(list, len(desc) > 0 && desc[0]))
}
